# @Author:HJT
# @Date: 2023/8/23


import inspect
import os
import re
from typing import Union, List
from pathlib import Path
from config.settings import BASE_PATH


def search_test_py(path: Union[os.PathLike, str], sub_dir='testcases') -> List:
    """ 搜索项目根目录下，所有以'test_开头的py文件 ' """
    base_dir = os.path.join(path, sub_dir)
    collect_paths = []
    print(base_dir)

    def recursion(f_path: str):
        if os.path.isfile(f_path):
            f_name = Path(f_path).name
            if f_name.startswith('test_') and f_name.endswith('.py'):
                collect_paths.append(f_path)
        else:
            root_ = f_path
            path_list = os.listdir(f_path)
            for f in path_list:
                full_path = os.path.join(root_, f)
                recursion(full_path)

    recursion(base_dir)

    return collect_paths


def _check_exist(code_, msg):
    """检查是否已存在msg内容"""
    return 1 if msg in code_ else 0


def update_source(t_file: str, extract_msg=', ids=lambda case: case["name"])'):
    """更新原py文件：读取 -> 更新指定位置 -> 重新写入"""
    t_file = Path(t_file).as_posix()
    pattern = r'@pytest\.mark\.parametrize\("caseinfo",.*?\)\)'

    with open(t_file, mode='r') as f:
        source_code = f.read().strip()
        tag_code = re.findall(pattern, source_code, re.DOTALL)
        for code_ in tag_code:
            if _check_exist(code_, extract_msg):
                continue

            new_code = code_[:-1] + extract_msg
            source_code = source_code.replace(code_, new_code)
        # print(source_code)

    with open(t_file, 'w', encoding='utf8') as f:
        f.write(source_code)


def run():
    """更新每个py文件的源代码"""
    # 1.查找目录下的所有目标文件
    paths = search_test_py(BASE_PATH)
    for test_file in paths:
        # 2.更新每一个目标文件
        try:
            update_source(test_file)
        except Exception as e:
            msg = f"""
                    文件更新失败，详细信息：
                        文件：{test_file}
                        报错：{e.__class__}  : {e}
    """
            raise Exception(msg)


if __name__ == '__main__':
    run()
